package com.hcjy.entity.resp;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.io.Serial;
import java.io.Serializable;
import java.util.HashMap;

/**
 * 标准响应体封装类
 * @author guqier
 * @version 1.0
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class R implements Serializable {

    @Serial
    private static final long serialVersionUID = 1L;

    @Getter
    public enum Archetype {

        /*
        通用状态码
         */
        SUCCESS(1, "success"),
        ERROR(0, "error"),

        /*
        业务错误状态码
         */
        PARAM_IS_INVAlID(101, "参数无效"),
        PARAM_IS_BLANK(102, "必要参数为空"),

        /* 用户错误  201 - 299  */
        USER_NOT_LOGIN(201, "用户未登录"),
        INVALID_TOKEN(202, "请先进行登录"),
        USER_NOT_EXIST(203, "手机号或密码错误"),
        USER_LOGIN_ERROR(204, "登陆失败，账号或者密码有误"),
        NOT_PERMISSION(205, "无权限访问"),
        TOKEN_EXPIRED(206, "登录已过期"),
        ERROR_AUTH_CODE(208, "验证码错误"),
        INVALID_PHONE(209, "无效的手机号"),


        /* 业务错误 301 - 399*/

        /* 数据错误 */
        CACHE_NOT_EXIST(401, "缓存不存在或已过期"),
        DATABASE_HANDLE_ERROR(402, "数据库处理失败"),

        /* 接口错误 */
        NO_HANDLER_FOUND(501, "接口不存在"),

        SYS_ERROR(999, "系统异常")

        ;

        //返回状态码
        private final Integer code;

        //返回消息
        private final String msg;


        Archetype(Integer code, String msg) {
            this.code = code;
            this.msg = msg;
        }

    }

    /**
     * 结果码，1为成功，其他为失败
     */
    private Integer code;

    /**
     * 响应消息
     */
    private String msg;

    /**
     * 响应数据体
     */
    private Object data;

    /**
     * 基于响应状态枚举的构造方法
     * @param responseEnum 响应状态枚举
     */
    public R(Archetype responseEnum) {
        this.code = responseEnum.getCode();
        this.msg = responseEnum.getMsg();
    }

    /**
     * 基于响应状态枚举和数据体的构造方法
     * @param responseEnum 响应状态枚举
     * @param data         响应数据
     */
    public R(Archetype responseEnum, Object data) {
        this.code = responseEnum.getCode();
        this.msg = responseEnum.getMsg();
        this.data = data;
    }

    /**
     * 通用响应体构造方法
     * @param key 响应数据的键
     * @param data 响应数据
     * @return 响应体
     * @param <T> 响应数据类型
     */
    public <T> R of(String key, T data) {
        this.data = new HashMap<String, Object>() {{
            put(key, data);
        }};
        return this;
    }

    /**
     * 通用成功响应
     * @param data 响应数据
     * @return 响应体
     */
    public static R success(Object data) {//请求成功信息
        return new R(Archetype.SUCCESS, data);
    }

    /**
     * 通用成功响应
     * @return 响应体
     */
    public static R success() {//请求成功信息
        return new R(Archetype.SUCCESS, null);
    }

    /**
     * 通用失败响应
     * @param code 响应码
     * @param msg  响应信息
     * @return 响应体
     */
    public static R fail(int code, String msg) {//请求失败信息
        return new R(code, msg, null);
    }

    /**
     * 通用失败响应
     * @param responseEnum 响应Code枚举
     * @return 响应体
     */
    public static R fail(Archetype responseEnum) {
        return new R(responseEnum, null);
    }

    /**
     * 通用失败响应
     * @param responseEnum 响应Code枚举
     * @param msg          响应信息
     * @return 响应体
     */
    public static R fail(Archetype responseEnum, String msg) {
        return new R(responseEnum.getCode(), msg, null);
    }

}
